﻿Imports Microsoft.Xna.Framework.Input

Namespace Messaging

    Public Enum MessageType
        WM_NULL = &H0
        WM_MOVE = &H3
        WM_SIZE = &H5
        WM_ACTIVATE = &H6
        WM_SETFOCUS = &H7
        WM_KILLFOCUS = &H8
        WM_ENABLE = &HA
        WM_SETTEXT = &HC
        WM_GETTEXT = &HD
        WM_GETTEXTLENGTH = &HE
        WM_FONTCHANGE = &H1D
        WM_KEYFIRST = &H100
        WM_KEYLAST = &H108
        WM_KEYDOWN = &H100
        WM_KEYUP = &H101
        WM_SYSKEYDOWN = &H104
        WM_SYSKEYUP = &H105
        WM_TIMER = &H113
        WM_MOUSEACTIVATE = &H21
        WM_MOUSEFIRST = &H200
        WM_MOUSELAST = &H209
        WM_MOUSEMOVE = &H200
        WM_MOUSEWHEEL = &H20A
        WM_LBUTTONDOWN = &H201
        WM_LBUTTONUP = &H202
        WM_LBUTTONDBLCLK = &H203
        WM_RBUTTONDOWN = &H204
        WM_RBUTTONUP = &H205
        WM_RBUTTONDBLCLK = &H206
#If NETFX_CORE Or WINDOWS_PHONE Then
        WM_TOUCH = &H240
        WM_GESTURE = &H119
#End If
        WM_USER = &H400
        WM_USER_RESERVED1 = &H400 + 1
        WM_USER_RESERVED2 = &H400 + 2
        WM_USER_RESERVED3 = &H400 + 3
        WM_USER_RESERVED4 = &H400 + 4
    End Enum

    Public Class Message
        Implements IDisposable

        Public Property HWnd() As Object
        Public Property Message() As MessageType

        ''' <summary>
        ''' The main message parameter.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property LParm() As Object
        ''' <summary>
        ''' The desired target of the message.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property WParam() As Object

        Public Property Time() As DateTime
        Public Property Pt() As Microsoft.Xna.Framework.Point
        Public Property Result() As Object

        Public Property Invalid() As Boolean = False

        Public Sub New()
            Me.HWnd = Nothing
            Me.Message = 0
            Me.LParm = Nothing
            Me.WParam = Nothing
            Me.Result = Nothing
        End Sub

        Public ReadOnly Property IsInputMessage() As Boolean
            Get
#If NETFX_CORE Or WINDOWS_PHONE Then
                Static Dim inputMsgs() As MessageType =
                    {
                        MessageType.WM_MOUSEACTIVATE,
                        MessageType.WM_KEYDOWN,
                        MessageType.WM_KEYUP,
                        MessageType.WM_MOUSEMOVE,
                        MessageType.WM_MOUSEWHEEL,
                        MessageType.WM_LBUTTONDOWN,
                        MessageType.WM_LBUTTONUP,
                        MessageType.WM_LBUTTONDBLCLK,
                        MessageType.WM_RBUTTONDOWN,
                        MessageType.WM_RBUTTONUP,
                        MessageType.WM_RBUTTONDBLCLK,
                        MessageType.WM_TOUCH,
                        MessageType.WM_GESTURE
                    }
#Else
                Static Dim inputMsgs() As MessageType =
                    {
                        MessageType.WM_MOUSEACTIVATE,
                        MessageType.WM_KEYDOWN,
                        MessageType.WM_KEYUP,
                        MessageType.WM_MOUSEMOVE,
                        MessageType.WM_MOUSEWHEEL,
                        MessageType.WM_LBUTTONDOWN,
                        MessageType.WM_LBUTTONUP,
                        MessageType.WM_LBUTTONDBLCLK,
                        MessageType.WM_RBUTTONDOWN,
                        MessageType.WM_RBUTTONUP,
                        MessageType.WM_RBUTTONDBLCLK
                    }
#End If
                Return inputMsgs.Contains(Me.Message)
            End Get
        End Property

        ''' <summary>
        ''' Create a message object.
        ''' </summary>
        ''' <param name="sender"></param>
        ''' <param name="msg"></param>
        ''' <param name="lparm">The main message parameter.</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal sender As Object, ByVal msg As MessageType, Optional ByVal lparm As Object = Nothing)
            Me.HWnd = sender
            Me.Message = msg
            Me.LParm = lparm
            Me.WParam = Nothing
            Me.Result = Nothing
        End Sub

        ''' <summary>
        ''' Create a message object.
        ''' </summary>
        ''' <param name="hwnd"></param>
        ''' <param name="msg"></param>
        ''' <param name="lparm">The main message parameter.</param>
        ''' <param name="wparm">The desired target of the message.</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Shared Function Create(ByVal hwnd As Object, ByVal msg As MessageType, Optional ByVal lparm As Object = Nothing, Optional ByVal wparm As Object = Nothing) As Message
            Dim ms = Mouse.GetState()
            Dim pt = New Microsoft.Xna.Framework.Point(ms.X, ms.Y)
            Return New Message(hwnd, msg, lparm) With {.WParam = wparm, .Time = DateTime.Now, .Pt = pt}
        End Function

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: dispose managed state (managed objects).
                    Me.Invalid = True
                End If
                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        'Protected Overrides Sub Finalize()
        '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class

End Namespace